#include <iostream>
#include <Trie.hpp>
#include <WordDataReader.hpp>
#include <sstream>
#include <Utility.hpp>
#include <cstdlib>
#include <ctime>
#include <GTrie.hpp>

int main (int argc, char * argv[]) {

	std::stringstream ss;
	srand(time(NULL));

	Trie * trie = new Trie();
	int qtyWords = trie->deserialize(std::cin);
	std::cerr << "There are " << qtyWords << 
		" distinct words\n";

	std::vector<std::string> words;

	trie->itemize(words);

	std::vector<int> remaining(words.size());

	delete trie;
	trie = new Trie();
	GTrie<int> * gtrie = new GTrie<int>();

	Utility::split(trie, gtrie, words, remaining);

	trie->serialize(ss);
	int qtyParts = trie->deserialize(ss);

	std::cerr << "There are " << qtyParts << 
		" distinct parts\n";

	int foundW = 0;
	long long generated(0);
	for (int found = 0; found < qtyParts; ) {
		std::string word = Utility::randomWord(true);
		generated++;
		
		bool search = 
			trie->retrieveUntil(word);
			
		if (search) {
			found++;
			trie->remove(word);
			
			std::vector<int> connections = 
				gtrie->retrieve(word);

			for(int i = 0; i < connections.size(); i++) {
				remaining[connections[i]]--;
				if (!remaining[connections[i]]) {
					foundW ++;
					std::cerr << foundW << " / " 
						<< qtyWords << std::endl; 
					std::cout << words[connections[i]] <<
						std::endl;
				}
			}

			gtrie->remove(word);
		}
	}
	std::cerr << generated << std::endl;

	return 0;
}
